package org.lex.ftp.ui;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.lex.net.Password;
import org.lex.net.ftp.FTPURL;
import org.lex.swing.DocumentAdapter;
import org.lex.swing.SelectAllWhenGainFocus;


public class URLPane extends JPanel {
	public JLabel serverLabel = null;
	public JTextField hostTextField = null;
	public JLabel portLabel = null;
	public JTextField portTextField = null;
	public JLabel userLabel = null;
	public JTextField userTextField = null;
	public JCheckBox anonymousCheckBox = null;
	public JLabel passwordLabel = null;
	public JPasswordField passwordField = null;
	public JLabel pathLabel = null;
	public JTextField pathTextField = null;
	private boolean contentChanged = false;

	/**
	 * This is the default constructor
	 */
	public URLPane() {
		super();
		initialize();
		this.hookActionHandler();
	}

	public boolean isContentChanged() {
		return contentChanged;
	}

	public void setContentChanged(boolean contentChanged) {
		this.contentChanged = contentChanged;
	}

	public void reset() {
		this.getHostTextField().setText("");
		this.getPortTextField().setText("21");
		this.getUserTextField().setText("");
		this.getAnonymousCheckBox().setSelected(true);
		this.getPasswordField().setText("");
		this.getPathTextField().setText("/");
	}

	public FTPURL getURL() {
		String host = hostTextField.getText().trim();
		int port = Integer.parseInt(portTextField.getText());
		Password auth = Password.ANONYMOUS;
		if (false == anonymousCheckBox.isSelected()) {
			String username = userTextField.getText();
			auth = new Password(username, getPasswordField().getPassword());
		}
		String path = pathTextField.getText().trim();
		return new FTPURL(auth, host, port, path);
	}

	public void setURL(FTPURL url) {
		this.getHostTextField().setText(url.getHost());
		this.getPortTextField().setText(Integer.toString(url.getPort()));
		this.getPathTextField().setText(url.getPath());
		if (true == url.isAnonymous()) {
			this.getAnonymousCheckBox().setSelected(true);
			this.getUserTextField().setText("");
			this.getPasswordField().setText("");
		} else {
			this.getAnonymousCheckBox().setSelected(false);
			Password autn = url.getAuthentication();
			this.getUserTextField().setText(autn.getUserName());
			this.getPasswordField().setText(new String(autn.getPassword()));
		}
	}

	private void hookActionHandler() {
		// if user/pass TextField content changed, unselect anonymous chackbox
		DocumentListener anoyListener = new DocumentAdapter() {
			@Override
			public void documentChanged(DocumentEvent e) {
				getAnonymousCheckBox().setSelected(false);
			}
		};
		this.userTextField.getDocument().addDocumentListener(anoyListener);
		this.getPasswordField().getDocument().addDocumentListener(anoyListener);
		// hook content-change listener
		DocumentListener contentChangeListener = new DocumentAdapter() {
			@Override
			public void documentChanged(DocumentEvent e) {
				setContentChanged(true);
			}
		};
		this.hostTextField.getDocument().addDocumentListener(contentChangeListener);
		this.userTextField.getDocument().addDocumentListener(contentChangeListener);
		this.portTextField.getDocument().addDocumentListener(contentChangeListener);
		this.passwordField.getDocument().addDocumentListener(contentChangeListener);
		this.pathTextField.getDocument().addDocumentListener(contentChangeListener);
		this.anonymousCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setContentChanged(true);
				if (true == anonymousCheckBox.isSelected()) {
					userTextField.setText("");
					passwordField.setText("");
				}
			}
		});
	}

	/**
	 * ����GUI
	 */
	private void initialize() {
		GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
		gridBagConstraints13.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints13.gridwidth = 3;
		gridBagConstraints13.gridx = 1;
		gridBagConstraints13.gridy = 4;
		gridBagConstraints13.weightx = 1.0;
		gridBagConstraints13.insets = new Insets(0, 0, 0, 0);
		GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
		gridBagConstraints12.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints12.gridx = 0;
		gridBagConstraints12.gridy = 4;
		gridBagConstraints12.anchor = GridBagConstraints.WEST;
		gridBagConstraints12.insets = new Insets(0, 0, 0, 5);
		pathLabel = new JLabel();
		pathLabel.setText("Path");
		GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
		gridBagConstraints11.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints11.gridwidth = 3;
		gridBagConstraints11.gridx = 1;
		gridBagConstraints11.gridy = 3;
		gridBagConstraints11.weightx = 1.0;
		gridBagConstraints11.insets = new Insets(0, 0, 5, 0);
		GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
		gridBagConstraints10.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints10.gridx = 0;
		gridBagConstraints10.gridy = 3;
		gridBagConstraints10.anchor = GridBagConstraints.WEST;
		gridBagConstraints10.insets = new Insets(0, 0, 5, 5);
		passwordLabel = new JLabel();
		passwordLabel.setText("Password");
		GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
		gridBagConstraints9.anchor = GridBagConstraints.WEST;
		gridBagConstraints9.insets = new Insets(0, 0, 5, 0);
		gridBagConstraints9.gridwidth = 2;
		gridBagConstraints9.gridx = 2;
		gridBagConstraints9.gridy = 2;
		gridBagConstraints9.fill = GridBagConstraints.HORIZONTAL;
		GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
		gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints8.gridx = 1;
		gridBagConstraints8.gridy = 2;
		gridBagConstraints8.weightx = 1.0;
		gridBagConstraints8.insets = new Insets(0, 0, 5, 5);
		GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
		gridBagConstraints7.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints7.gridx = 0;
		gridBagConstraints7.gridy = 2;
		gridBagConstraints7.anchor = GridBagConstraints.WEST;
		gridBagConstraints7.insets = new Insets(0, 0, 5, 5);
		userLabel = new JLabel();
		userLabel.setText("User");
		userLabel.setHorizontalTextPosition(SwingConstants.TRAILING);
		userLabel.setVerticalTextPosition(SwingConstants.CENTER);
		userLabel.setHorizontalAlignment(SwingConstants.LEADING);
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints5.gridwidth = 1;
		gridBagConstraints5.gridx = 3;
		gridBagConstraints5.gridy = 1;
		gridBagConstraints5.ipadx = 0;
		gridBagConstraints5.weightx = 0.0D;
		gridBagConstraints5.insets = new Insets(0, 0, 5, 0);
		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
		gridBagConstraints4.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints4.gridy = 1;
		gridBagConstraints4.anchor = GridBagConstraints.WEST;
		gridBagConstraints4.gridx = 2;
		portLabel = new JLabel();
		portLabel.setText("Port");
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints3.gridx = 1;
		gridBagConstraints3.gridy = 1;
		gridBagConstraints3.weightx = 1.0;
		gridBagConstraints3.insets = new Insets(0, 0, 5, 5);
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints2.gridx = 0;
		gridBagConstraints2.gridy = 1;
		gridBagConstraints2.anchor = GridBagConstraints.WEST;
		gridBagConstraints2.insets = new Insets(0, 0, 5, 5);
		serverLabel = new JLabel();
		serverLabel.setText("Server");
		this.setLayout(new GridBagLayout());
		this.setSize(300, 107);
		this.add(serverLabel, gridBagConstraints2);
		this.add(getHostTextField(), gridBagConstraints3);
		this.add(portLabel, gridBagConstraints4);
		this.add(getPortTextField(), gridBagConstraints5);
		this.add(userLabel, gridBagConstraints7);
		this.add(getUserTextField(), gridBagConstraints8);
		this.add(getAnonymousCheckBox(), gridBagConstraints9);
		this.add(passwordLabel, gridBagConstraints10);
		this.add(getPasswordField(), gridBagConstraints11);
		this.add(pathLabel, gridBagConstraints12);
		this.add(getPathTextField(), gridBagConstraints13);
	}

	public JTextField getHostTextField() {
		if (hostTextField == null) {
			hostTextField = new JTextField();
			this.hostTextField.addFocusListener(SelectAllWhenGainFocus.getInstance());
		}
		return hostTextField;
	}

	public JTextField getPortTextField() {
		if (portTextField == null) {
			portTextField = new JTextField();
			portTextField.setText("21");
			portTextField.setHorizontalAlignment(JTextField.CENTER);
			portTextField.setPreferredSize(new Dimension(32, 20));
			this.portTextField.addFocusListener(SelectAllWhenGainFocus.getInstance());
		}
		return portTextField;
	}

	@SuppressWarnings("deprecation")
	public JTextField getUserTextField() {
		if (userTextField == null) {
			userTextField = new JTextField();
			userTextField.setNextFocusableComponent(this.getPasswordField());
			userTextField.addFocusListener(SelectAllWhenGainFocus.getInstance());
		}
		return userTextField;
	}

	public JCheckBox getAnonymousCheckBox() {
		if (anonymousCheckBox == null) {
			anonymousCheckBox = new JCheckBox();
			anonymousCheckBox.setSelected(true);
			anonymousCheckBox.setText("Anonymous");
		}
		return anonymousCheckBox;
	}

	public JPasswordField getPasswordField() {
		if (passwordField == null) {
			passwordField = new JPasswordField();
			passwordField.setEchoChar('*');
			passwordField.addFocusListener(SelectAllWhenGainFocus.getInstance());
		}
		return passwordField;
	}

	public JTextField getPathTextField() {
		if (pathTextField == null) {
			pathTextField = new JTextField("/");
			this.pathTextField.addFocusListener(SelectAllWhenGainFocus.getInstance());
		}
		return pathTextField;
	}

}
